package com.hivekion.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hivekion.common.core.SystemConstant;
import com.hivekion.common.entity.PagedResultVo;
import com.hivekion.common.entity.SelectOption;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.system.domain.SysDictData;
import com.hivekion.system.domain.vo.*;
import com.hivekion.system.mapper.SysDictDataMapper;
import com.hivekion.system.service.ISysDictDataService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysDictDataService implements ISysDictDataService {

      @Autowired
      SysDictDataMapper dataMapper;

      @Autowired
      private RedisUtil redisUtil;

      @Override
      public boolean add(SysDictDataCreateVo createVo) {
	    SysDictData data = new SysDictData();
	    BeanUtils.copyProperties(createVo, data);
	    return dataMapper.insert(data) > 0;
      }

      @Override
      public boolean edit(SysDictDataUpdateVo updateVo) {
	    SysDictData data = dataMapper.selectById(updateVo.getId());
	    BeanUtils.copyProperties(updateVo, data);
	    return dataMapper.updateById(data) > 0;
      }

      @Override
      public boolean remove(String key) {
	    return dataMapper.deleteById(key) > 0;
      }

      @Override
      public SysDictDataModelVo get(String key) {
	    SysDictData data = dataMapper.selectById(key);
	    SysDictDataModelVo vo = new SysDictDataModelVo();
	    BeanUtils.copyProperties(data, vo);
	    return vo;
      }

      @Override
      public PagedResultVo<SysDictDataViewVo> getList(SysDictDataSearchPageInputVo inputVo) {
	    LambdaQueryWrapper<SysDictData> queryWrapper = Wrappers.lambdaQuery();
	    queryWrapper.eq(SysDictData::getDictCode, inputVo.getDictCode());
	    queryWrapper.and(
		    StringUtils.isNotEmpty(inputVo.getFilter()),
		    t ->
			    t.like(SysDictData::getDictLabel, inputVo.getFilter())
				    .or()
				    .like(SysDictData::getDictValue, inputVo.getFilter()));
	    Page<SysDictData> dataPage = new Page<>(inputVo.getPageNum(), inputVo.getPageSize());
	    dataPage.addOrder(new OrderItem("sort_code", true));
	    IPage<SysDictData> data = dataMapper.selectPage(dataPage, queryWrapper);
	    List<SysDictDataViewVo> list =
		    data.getRecords().stream()
			    .map(
				    t -> {
					  SysDictDataViewVo vo = new SysDictDataViewVo();
					  BeanUtils.copyProperties(t, vo);
					  return vo;
				    })
			    .collect(Collectors.toList());
	    PagedResultVo<SysDictDataViewVo> resultVo =
		    new PagedResultVo<SysDictDataViewVo>(inputVo, (int) data.getTotal(), list);
	    return resultVo;
      }

      @Override
      public List<SelectOption> getOptions(String dictType) {
	    LambdaQueryWrapper<SysDictData> queryWrapper = Wrappers.lambdaQuery();
	    queryWrapper.eq(SysDictData::getDictCode, dictType);
	    List<SysDictData> list = dataMapper.selectList(queryWrapper);
	    List<SelectOption> data =
		    list.stream()
			    .sorted(Comparator.comparing(SysDictData::getSortCode))
			    .map(
				    item -> {
					  SelectOption option = new SelectOption();
					  option.setTitle(item.getDictLabel());
					  option.setValue(item.getId());
					  option.setKey(item.getId());
					  option.setDisabled(item.getStatus() != 0);
					  return option;
				    })
			    .collect(Collectors.toList());
	    return data;
      }
      @Override
      public List<SysDictData> getAllData() {
	    if (redisUtil.hasKey(SystemConstant.redis_dict_data)) {
		  List<SysDictData> list =
			  JSON.parseArray(
				  redisUtil.get(SystemConstant.redis_dict_data).toString(),
				  SysDictData.class);
		  return list;
	    } else {
		  List<SysDictData> dataList = dataMapper.selectList(null);
		  redisUtil.set(SystemConstant.redis_dict_data, JSON.toJSONString(dataList));
		  return dataList;
	    }
      }
}
